"""
全局配置管理模块
统一管理所有环境变量和配置项
"""
import os
from typing import Dict, Any, Optional, List, Union
from pydantic_settings import BaseSettings, SettingsConfigDict
from pydantic import Field, validator
import json


class DatabaseSettings(BaseSettings):
    """数据库配置"""
    DATABASE_URL: str = Field(
        default="postgresql://postgres:123456@localhost:5432/toolplatform",
        description="数据库连接URL"
    )
    DATABASE_POOL_SIZE: int = Field(
        default=10,
        description="数据库连接池大小"
    )
    DATABASE_MAX_OVERFLOW: int = Field(
        default=20,
        description="数据库连接池最大溢出连接数"
    )
    DATABASE_POOL_RECYCLE: int = Field(
        default=3600,
        description="数据库连接回收时间(秒)"
    )
    DATABASE_POOL_TIMEOUT: int = Field(
        default=30,
        description="获取数据库连接的超时时间(秒)"
    )
    DATABASE_CONNECT_TIMEOUT: int = Field(
        default=10,
        description="数据库连接超时时间(秒)"
    )


class SecuritySettings(BaseSettings):
    """安全配置"""
    SECRET_KEY: str = Field(
        default="fastapi-platform-2025-super-secret-key-for-development-only",
        description="JWT密钥"
    )
    ALGORITHM: str = Field(default="HS256", description="JWT算法")
    ACCESS_TOKEN_EXPIRE_MINUTES: int = Field(default=30, description="访问令牌过期时间(分钟)")
    REFRESH_TOKEN_EXPIRE_DAYS: int = Field(default=7, description="刷新令牌过期时间(天)")


class ServerSettings(BaseSettings):
    """服务器配置"""
    HOST: str = Field(default="0.0.0.0", description="服务器主机")
    PORT: int = Field(default=8989, description="服务器端口")
    RELOAD: bool = Field(default=False, description="是否自动重载")
    RELOAD_DIRS: List[str] = Field(default=["app"], description="重载监控目录")


class CorsSettings(BaseSettings):
    """CORS配置"""
    BACKEND_CORS_ORIGINS: List[str] = Field(
        default=[
            "http://localhost:3000",
            "http://localhost:5173",
            "http://localhost:5174",
            "http://localhost:5175",
            "http://localhost:5176",
            "http://localhost:5177",
            "http://localhost:8989",
            "http://127.0.0.1:3000",
            "http://127.0.0.1:5173",
            "http://127.0.0.1:5174",
            "http://127.0.0.1:5175",
            "http://127.0.0.1:5176",
            "http://127.0.0.1:5177",
            "http://127.0.0.1:8989"
        ],
        description="允许的CORS源"
    )

    @validator("BACKEND_CORS_ORIGINS", pre=True)
    def assemble_cors_origins(cls, v: Union[str, List[str]]) -> List[str]:
        """解析CORS源配置"""
        if isinstance(v, str):
            if v.strip().startswith("["):
                try:
                    return json.loads(v)
                except (json.JSONDecodeError, ValueError):
                    v = v.strip("[]")
                    return [i.strip().strip('"\'') for i in v.split(",") if i.strip()]
            else:
                return [i.strip() for i in v.split(",") if i.strip()]
        elif isinstance(v, list):
            return v
        return []


class RedisSettings(BaseSettings):
    """Redis配置"""
    REDIS_URL: str = Field(default="redis://localhost:6379", description="Redis连接URL")
    
    # Celery配置
    CELERY_BROKER_URL: str = Field(default="redis://localhost:6379/1", description="Celery消息代理URL")
    CELERY_RESULT_BACKEND: str = Field(default="redis://localhost:6379/2", description="Celery结果后端URL")


class FileUploadSettings(BaseSettings):
    """文件上传配置"""
    UPLOAD_DIR: str = Field(default="uploads", description="上传文件目录")
    MAX_FILE_SIZE: int = Field(default=10 * 1024 * 1024, description="最大文件大小(字节)")
    ALLOWED_FILE_TYPES: List[str] = Field(
        default=["jpg", "jpeg", "png", "gif", "pdf", "txt", "md"],
        description="允许的文件类型"
    )

    @validator("ALLOWED_FILE_TYPES", pre=True)
    def assemble_allowed_file_types(cls, v: Union[str, List[str]]) -> List[str]:
        """解析允许的文件类型"""
        if isinstance(v, str):
            if v.strip().startswith("["):
                try:
                    return json.loads(v)
                except (json.JSONDecodeError, ValueError):
                    v = v.strip("[]")
                    return [i.strip().strip('"\'') for i in v.split(",") if i.strip()]
            else:
                return [i.strip() for i in v.split(",") if i.strip()]
        elif isinstance(v, list):
            return v
        return []


class EmailSettings(BaseSettings):
    """邮件配置"""
    SMTP_HOST: str = Field(default="smtp.gmail.com", description="SMTP服务器主机")
    SMTP_PORT: int = Field(default=587, description="SMTP服务器端口")
    SMTP_TLS: bool = Field(default=True, description="是否使用TLS")
    SMTP_USER: str = Field(default="your-email@gmail.com", description="SMTP用户名")
    SMTP_PASSWORD: str = Field(default="your-app-password", description="SMTP密码")
    EMAILS_FROM_EMAIL: str = Field(default="your-email@gmail.com", description="发件人邮箱")
    EMAILS_FROM_NAME: str = Field(default="FastAPI Platform", description="发件人名称")


class LoggingSettings(BaseSettings):
    """日志配置"""
    model_config = SettingsConfigDict(
        env_prefix="LOG_", 
        env_parse_numbers=True, 
        env_parse_enums=True,
        extra="ignore"
    )
    
    # 基础日志配置
    LOG_LEVEL: str = Field(default="INFO", description="日志级别")
    LOG_FILE: str = Field(default="logs/app.log", description="日志文件路径")
    LOG_TO_CONSOLE: bool = Field(default=True, description="是否输出到控制台")
    LOG_TO_FILE: bool = Field(default=True, description="是否输出到文件")
    LOG_COLORFUL: bool = Field(default=True, description="是否彩色输出")

    # 企业级日志配置
    LOG_ENABLE_CONSOLE: bool = Field(default=True, description="启用控制台日志")
    LOG_ENABLE_FILE: bool = Field(default=True, description="启用文件日志")
    LOG_ENABLE_JSON: bool = Field(default=False, description="启用JSON格式日志")
    LOG_ENABLE_STRUCTURED: bool = Field(default=True, description="启用结构化日志")
    LOG_FILE_PREFIX: str = Field(default="app", description="日志文件前缀")
    LOG_MAX_FILE_SIZE: int = Field(default=50 * 1024 * 1024, description="日志文件最大大小(字节)")
    LOG_BACKUP_COUNT: int = Field(default=5, description="日志文件备份数量")


class PaginationSettings(BaseSettings):
    """分页配置"""
    model_config = SettingsConfigDict(env_prefix="PAGINATION_", env_parse_numbers=True, env_parse_enums=True)
    
    DEFAULT_PAGE_SIZE: int = Field(default=20, description="默认页面大小")
    MAX_PAGE_SIZE: int = Field(default=100, description="最大页面大小")


class HotApiSettings(BaseSettings):
    """热点API配置"""
    model_config = SettingsConfigDict(
        env_prefix="HOT_", 
        env_parse_numbers=True, 
        env_parse_enums=True,
        extra="ignore"
    )
    
    # 热点API缓存配置
    CACHE_TTL: int = Field(default=300, description="热点API缓存过期时间(秒)")
    MAX_CACHE_SIZE: int = Field(default=1000, description="热点API缓存最大数量")

    # 各平台API配置
    ZHIHU_COOKIE: str = Field(default="", description="知乎Cookie")
    BILIBILI_COOKIE: str = Field(default="", description="B站Cookie")
    WEIBO_COOKIE: str = Field(default="", description="微博Cookie")

    # 热点API限流配置
    RATE_LIMIT: int = Field(default=100, description="热点API限流次数")
    RATE_LIMIT_PERIOD: int = Field(default=60, description="热点API限流周期(秒)")


class LLMProviderConfig(BaseSettings):
    """LLM提供商基础配置"""
    
    model_config = SettingsConfigDict(protected_namespaces=())
    
    name: str = Field(..., description="提供商名称")
    api_base: str = Field(..., description="API基础URL")
    api_key: str = Field(..., description="API密钥")
    model_name: str = Field(..., description="模型名称")
    max_tokens: int = Field(default=4000, description="最大token数")
    temperature: float = Field(default=0.7, description="温度参数")
    timeout: int = Field(default=30, description="超时时间(秒)")


class LLMSettings(BaseSettings):
    """LLM统一配置"""
    # 默认配置
    DEFAULT_PROVIDER: str = Field(default="openai", description="默认提供商")
    DEFAULT_MODEL: str = Field(default="gpt-3.5-turbo", description="默认模型")
    
    # 全局限制
    MAX_TOKENS: int = Field(default=4000, description="最大token限制")
    MAX_CONVERSATION_TOKENS: int = Field(default=8000, description="对话最大token限制")
    
    # 流式响应配置
    STREAM_CHUNK_SIZE: int = Field(default=1024, description="流式响应块大小")
    STREAM_TIMEOUT: int = Field(default=60, description="流式响应超时时间")
    
    # 重试配置
    MAX_RETRIES: int = Field(default=3, description="最大重试次数")
    RETRY_DELAY: float = Field(default=1.0, description="重试延迟(秒)")
    
    # 缓存配置
    CACHE_TTL: int = Field(default=3600, description="缓存过期时间(秒)")
    
    # 提供商配置
    PROVIDERS: Dict[str, Dict[str, Any]] = Field(
        default_factory=lambda: {
            "openai": {
                "models": ["gpt-3.5-turbo", "gpt-4", "gpt-4-turbo-preview"],
                "max_tokens": 4000,
                "temperature_range": [0, 2]
            },
            "anthropic": {
                "models": ["claude-3-haiku-20240307", "claude-3-sonnet-20240229", "claude-3-opus-20240229"],
                "max_tokens": 4000,
                "temperature_range": [0, 1]
            },
            # "google": {
            #     "models": ["gemini-pro", "gemini-pro-vision"],
            #     "max_tokens": 4000,
            #     "temperature_range": [0, 1]
            # }
        },
        description="支持的提供商和模型"
    )

    # OpenAI配置
    OPENAI_API_KEY: str = Field(default="", description="OpenAI API密钥")
    OPENAI_MODEL: str = Field(default="gpt-3.5-turbo", description="OpenAI模型")
    OPENAI_MAX_TOKENS: int = Field(default=4000, description="OpenAI最大token数")
    OPENAI_TEMPERATURE: float = Field(default=0.7, description="OpenAI温度参数")

    # Azure OpenAI配置
    AZURE_OPENAI_API_KEY: str = Field(default="", description="Azure OpenAI API密钥")
    AZURE_OPENAI_ENDPOINT: str = Field(default="https://your-resource.openai.azure.com/", description="Azure OpenAI端点")
    AZURE_OPENAI_MODEL: str = Field(default="gpt-35-turbo", description="Azure OpenAI模型")
    AZURE_MAX_TOKENS: int = Field(default=4000, description="Azure OpenAI最大token数")

    # Anthropic配置
    ANTHROPIC_API_KEY: str = Field(default="", description="Anthropic API密钥")
    ANTHROPIC_MODEL: str = Field(default="claude-3-haiku-20240307", description="Anthropic模型")
    ANTHROPIC_MAX_TOKENS: int = Field(default=4000, description="Anthropic最大token数")
    ANTHROPIC_TEMPERATURE: float = Field(default=0.7, description="Anthropic温度参数")

    # Google配置
    # GOOGLE_API_KEY: str = Field(default="", description="Google API密钥")
    # GOOGLE_MODEL: str = Field(default="gemini-pro", description="Google模型")
    # GOOGLE_MAX_TOKENS: int = Field(default=4000, description="Google最大token数")


class GlobalSettings(BaseSettings):
    """全局配置类
    整合所有配置模块
    """
    # 项目基本信息
    PROJECT_NAME: str = Field(default="FastAPI Platform", description="项目名称")
    VERSION: str = Field(default="1.0.0", description="项目版本")
    DESCRIPTION: str = Field(default="基于RBAC的权限管理系统 + DailyHotApi热点服务", description="项目描述")
    ENVIRONMENT: str = Field(default="development", description="运行环境")
    DEBUG: bool = Field(default=True, description="调试模式")

    # 配置子模块
    database: DatabaseSettings = Field(default_factory=DatabaseSettings)
    security: SecuritySettings = Field(default_factory=SecuritySettings)
    server: ServerSettings = Field(default_factory=ServerSettings)
    cors: CorsSettings = Field(default_factory=CorsSettings)
    redis: RedisSettings = Field(default_factory=RedisSettings)
    file_upload: FileUploadSettings = Field(default_factory=FileUploadSettings)
    email: EmailSettings = Field(default_factory=EmailSettings)
    logging: LoggingSettings = Field(default_factory=LoggingSettings)
    pagination: PaginationSettings = Field(default_factory=PaginationSettings)
    hot_api: HotApiSettings = Field(default_factory=HotApiSettings)
    llm: LLMSettings = Field(default_factory=LLMSettings)

    model_config = SettingsConfigDict(
        env_file=".env",
        env_file_encoding="utf-8",
        case_sensitive=False,
        env_nested_delimiter="__",
        protected_namespaces=(),
        env_parse_numbers=True,
        env_parse_enums=True,
        extra="ignore"
    )

    def get_provider_config(self, provider_name: str) -> Optional[Dict[str, Any]]:
        """获取特定LLM提供商的完整配置"""
        if provider_name == "openai":
            return {
                "name": "openai",
                "api_base": "https://api.openai.com/v1",
                "api_key": self.llm.OPENAI_API_KEY,
                "model_name": self.llm.OPENAI_MODEL,
                "max_tokens": self.llm.OPENAI_MAX_TOKENS,
                "temperature": self.llm.OPENAI_TEMPERATURE
            }
        elif provider_name == "azure":
            return {
                "name": "azure",
                "api_base": self.llm.AZURE_OPENAI_ENDPOINT,
                "api_key": self.llm.AZURE_OPENAI_API_KEY,
                "model_name": self.llm.AZURE_OPENAI_MODEL,
                "max_tokens": self.llm.AZURE_MAX_TOKENS,
                "temperature": 0.7
            }
        elif provider_name == "anthropic":
            return {
                "name": "anthropic",
                "api_base": "https://api.anthropic.com",
                "api_key": self.llm.ANTHROPIC_API_KEY,
                "model_name": self.llm.ANTHROPIC_MODEL,
                "max_tokens": self.llm.ANTHROPIC_MAX_TOKENS,
                "temperature": self.llm.ANTHROPIC_TEMPERATURE
            }
        # elif provider_name == "google":
        #     return {
        #         "name": "google",
        #         "api_base": "https://generativelanguage.googleapis.com/v1beta",
        #         "api_key": self.llm.GOOGLE_API_KEY,
        #         "model_name": self.llm.GOOGLE_MODEL,
        #         "max_tokens": self.llm.GOOGLE_MAX_TOKENS,
        #         "temperature": 0.7
        #     }
        return None

    def get_active_providers(self) -> Dict[str, Dict[str, Any]]:
        """获取所有已配置的LLM提供商"""
        active_providers = {}
        providers = ["openai", "azure", "anthropic", "google"]
        
        for provider in providers:
            config = self.get_provider_config(provider)
            if config and config["api_key"]:
                active_providers[provider] = config
        
        return active_providers

    def get_models(self, provider_name: str) -> List[str]:
        """获取特定提供商支持的模型列表"""
        return self.llm.PROVIDERS.get(provider_name, {}).get("models", [])


# 创建全局配置实例
settings = GlobalSettings()


# 为了兼容现有代码，提供LLM配置的快捷访问方式
class LLMConfig:
    """LLM配置管理器（兼容层）"""
    
    def __init__(self):
        self.settings = settings.llm
        
    def get_provider(self, provider_name: str) -> Optional[Dict[str, Any]]:
        """获取特定提供商配置"""
        return settings.get_provider_config(provider_name)
    
    def get_active_providers(self) -> Dict[str, Dict[str, Any]]:
        """获取所有已配置的提供商"""
        return settings.get_active_providers()
    
    def get_models(self, provider_name: str) -> List[str]:
        """获取提供商支持的模型列表"""
        return settings.get_models(provider_name)


# 创建LLM配置实例
llm_config = LLMConfig()